﻿using Pay.Core;
using Pay.Data;
using Pay.DTO;
using Pay.IService;
using Pay.Service.Cache;
using Pay.TO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;
using Flurl.Util;
using System.Net.Http;
using System.Collections.Specialized;

namespace Pay.Service {
    public class ActivityService : ServiceBase, IActivityService, IDisposable {
        private IUnitOfWork _iUnitOfWork;
        public ActivityService(IUnitOfWork iUnitOfWork) : base(iUnitOfWork) {
            _iUnitOfWork = iUnitOfWork;
        }

        #region 后台活动管理
        /// <summary>
        /// 获得活动列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public PagedResult<activity_dto> GetActivitys(ActivityQuery query) {
            AutoUpdateActivityStatus();
            var filter = PredicateBuilder.True<Activity>();
            if (!string.IsNullOrEmpty(query.title))
                filter = filter.And(c => c.Title == query.title);
            if (!string.IsNullOrEmpty(query.status)) {
                int value = int.Parse(query.status);
                filter = filter.And(c => c.Status == (EActivityStatus)value);
            }
            if (!string.IsNullOrEmpty(query.begin_time)) {
                DateTime time = DateTime.Parse(query.begin_time);
                filter = filter.And(c => c.EndTime >= time);
            }
            if (!string.IsNullOrEmpty(query.end_time)) {
                DateTime time = DateTime.Parse(query.end_time).AddDays(1);
                filter = filter.And(c => c.BeginTime <= time);
            }
            List<string> specialMobileList = new List<string>() { "13785555312" };
            List<long> managerIds = context.Manages.Where(c => specialMobileList.Contains(c.Mobile)).Select(c => c.Id).ToList();
            if(managerIds != null && managerIds.Count() > 0 && managerIds.Contains(query.curManagerId)) {
                filter = filter.And(c => c.CreateByManagerId == query.curManagerId);
            }

            var result = context.Activity.FromCachePaged<Activity, activity_dto>(query.page, query.size, filter, orderBy => orderBy.OrderBy(c => c.Status).ThenBy(o => o.Type));
            return result;
        }

        /// <summary>
        /// 获得活动
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public activity_dto GetActivity(long id) {
            return context.Activity.Where(c => c.Id == id).FromCacheFirstOrDefault<Activity, activity_dto>();
        }

        public activity_dto GetActivity(EActivityType type) {
            return context.Activity.Where(s => s.Type == type).FromCacheFirstOrDefault<Activity, activity_dto>("Activity");
        }
        /// <summary>
        /// 根据指定类型 获得进行中的活动
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public activity_dto GetAvailableActivity(EActivityType type) {
            var time = DateTime.Now;
            return context.Activity.Where(c => c.Type == type && c.BeginTime <= time && c.EndTime >= time).FirstOrDefault().ToDtoObject<activity_dto>();
        }

        public void UpdateActivity(EActivityType type) {
            var model = context.Activity.FirstOrDefault(s => s.Type == type);
            model.ClickNum += 1;
            _iUnitOfWork.Commit();
        }

        /// <summary>
        /// 新增活动
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ResultMessage<int> AddActivity(activity_dto dto, long curManagerId) {
            if (context.Activity.Exist(o => o.Type == dto.type && dto.type != EActivityType.ProductTimeBuy 
                                        && dto.type != EActivityType.ProductCashRedDrill && dto.type != EActivityType.ProductOnlyRedDrill))
                return new ResultMessage<int>(501, "所选活动类型已存在，不能重复添加");
            if (dto.begin_time > dto.end_time)
                return new ResultMessage<int>(501, "活动开始时间不能大于结束时间");
            DateTime timeNow = DateTime.Now;
            if (dto.type == EActivityType.ProductTimeBuy || dto.type == EActivityType.ProductCashRedDrill || dto.type == EActivityType.ProductOnlyRedDrill) {
                if (dto.preheat_time == null)
                    throw new ServerErrorException("请输入预热开始时间");
                if (dto.preheat_time > dto.begin_time)
                    throw new ServerErrorException("预热开始时间不能大于活动开始时间");
            }
            List<string> specialMobileList = new List<string>() { "13785555312" };
            List<long> managerIds = context.Manages.Where(c => specialMobileList.Contains(c.Mobile)).Select(c => c.Id).ToList();
            if (managerIds != null && managerIds.Count() > 0 && managerIds.Contains(curManagerId) && dto.type != EActivityType.ProductCashRedDrill) {
                throw new ServerErrorException("当前账号只允许发布红钻+现金类型的活动");
            }
            Activity model = new Activity();
            model.CreateByManagerId = curManagerId;
            dto.ToDtoObject(model);
            context.Activity.Add(model);
            int result = _iUnitOfWork.Commit("Activity");
            return ResultToJson.Json(result > 0 ? " 保存成功" : "保存失败", result);
        }

        /// <summary>
        /// 更新活动
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ResultMessage<int> UpdateActivity(activity_dto dto) {
            Activity model = context.Activity.FindById(dto.id);
            if (model.Type == EActivityType.ProductTimeBuy && model.EndTime <= DateTime.Now)
                throw new ServerErrorException("该限时购活动已结束，不允许修改");
            if (model.Type != dto.type && context.Activity.Exist(o => o.Type == dto.type && dto.type != EActivityType.ProductTimeBuy
                                        && dto.type != EActivityType.ProductCashRedDrill && dto.type != EActivityType.ProductOnlyRedDrill))
                return new ResultMessage<int>(501, "所选活动类型已存在，不能重复添加");
            if (dto.begin_time > dto.end_time)
                return new ResultMessage<int>(501, "活动开始时间不能大于结束时间");
            if (model.Type != dto.type)
                throw new ServerErrorException("活动类型不允许修改");
            DateTime timeNow = DateTime.Now;
            if (dto.type == EActivityType.ProductTimeBuy || dto.type == EActivityType.ProductCashRedDrill || dto.type == EActivityType.ProductOnlyRedDrill) {
                if (dto.preheat_time == null)
                    throw new ServerErrorException("请输入预热开始时间");
                if (dto.preheat_time > dto.begin_time)
                    throw new ServerErrorException("预热开始时间不能大于活动开始时间");
            }
            if (model.Status != EActivityStatus.Finished && dto.status == EActivityStatus.Finished && dto.end_time >= DateTime.Now && model.EndTime == dto.end_time) {//没改结束时间，只把状态设为立即结束，则把结束时间设为当前时间，提前结束活动
                dto.end_time = DateTime.Now;
            }
            List<string> cacheList = new List<string>() { "Activity" };
            if (dto.type != EActivityType.WorldCup) {
                var productIds = context.ProductActivity.Where(o => o.ActivityId == model.Id).Select(o => o.ProductId).ToList() ?? new List<long>();
                foreach (var productId in productIds)
                    cacheList.Add("ProductActivity" + productId);
            }

            dto.ToDtoObject(model);
            int result = _iUnitOfWork.Commit(cacheList.ToArray());
            return ResultToJson.Json(result > 0 ? " 保存成功" : "未做任何修改", result);
        }

        /// <summary>
        /// 修改活动状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public int UpdateActivityStatus(long id, int status) {
            Activity model = context.Activity.FindById(id);
            model.Status = (EActivityStatus)(status);
            if (model.Status == EActivityStatus.Finished && model.EndTime > DateTime.Now) {
                model.EndTime = DateTime.Now;
            }
            List<string> cacheList = new List<string>() { "Activity" };
            if (model.Type != EActivityType.WorldCup) {
                var productIds = context.ProductActivity.Where(o => o.ActivityId == model.Id).Select(o => o.ProductId).ToList() ?? new List<long>();
                foreach (var productId in productIds)
                    cacheList.Add("ProductActivity" + productId);
            }
            int result = _iUnitOfWork.Commit(cacheList.ToArray());
            return result;
        }

        /// <summary>
        /// 更新限时购云商城首页显示状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isShow"></param>
        /// <returns></returns>
        public bool UpdateIndexShow(long id, int isShow) {
            var model = context.Activity.FindById(id);
            if (model.Type != EActivityType.ProductTimeBuy && model.Type != EActivityType.ProductCashRedDrill)
                throw new ServerErrorException("该活动类型不允许修改首页显示状态");
            model.IsIndexShow = isShow == 0 ? false:true;
            return _iUnitOfWork.Commit("Activity") > 0;
        }
        #endregion

        /// <summary>
        /// 获得云商城首页限时购活动列表
        /// </summary>
        /// <returns></returns>
        public List<activity_dto> GetIndexTimeBuy() {
            return context.Activity.Where(s => (s.Type == EActivityType.ProductTimeBuy || s.Type == EActivityType.ProductCashRedDrill)
                                          && s.IsIndexShow == true).OrderBy(o => o.BeginTime).ToDtoList<activity_dto>();
        }

        /// <summary>
        /// 自动更新活动状态
        /// </summary>
        private void AutoUpdateActivityStatus() {
            var list = context.Activity.ToList();
            if (list != null && list.Count() > 0) {
                bool isNeedCommit = false;
                foreach (var activity in list) {
                    if (activity.BeginTime > DateTime.Now && activity.Status != EActivityStatus.NotStarted) {//未开始
                        activity.Status = EActivityStatus.NotStarted;
                        isNeedCommit = true;
                    }
                    if (activity.BeginTime <= DateTime.Now && activity.EndTime >= DateTime.Now && activity.Status != EActivityStatus.Underway) {//进行中
                        activity.Status = EActivityStatus.Underway;
                        isNeedCommit = true;
                    }
                    if (activity.EndTime < DateTime.Now && activity.Status != EActivityStatus.Finished) {//已结束
                        activity.Status = EActivityStatus.Finished;
                        isNeedCommit = true;
                    }
                }

                if (isNeedCommit)
                    _iUnitOfWork.Commit("Activity");
            }
        }
    }
}
